package com.swpu.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.swpu.project.common.BaseResponse;
import com.swpu.project.function.SetFunction;
import com.swpu.project.mapper.StandardMapper;
import com.swpu.project.model.dto.data.StandardDto;
import com.swpu.project.model.entity.*;
import com.swpu.project.model.page.PageDto;
import com.swpu.project.model.page.PageQuery;
import com.swpu.project.service.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author swpuyanxiegroup1
 * @since 2024-07-29
 */
@Service
public class StandardServiceImpl extends ServiceImpl<StandardMapper, Standard> implements IStandardService
{
    private static  final  String HEAVY_METAL_PREFIX="heavy_metal_";
    private static  final  String  NON_HEAVY_METAL_PREFIX="non_heavy_metal_";
    private static  final  String   MINERAL_PREFIX="mineral_";
    private static  final  String   RADIATION_PREFIX="radiation_";

    @Resource
    IHeavyMetalService iHeavyMetalService;
   @Resource
    INonHeavyMetalService iNonHeavyMetalService;
   @Resource
    IMineralService iMineralService;
    @Resource
    IRadiationService iRadiationService;
    @Override
    public BaseResponse queryStandard(PageQuery pageQuery)
     {
        lambdaQuery().eq(Standard::getStandardId,"2").list();

         QueryWrapper<Standard> standardQueryWrapper = new QueryWrapper<>();
         Map queryBy = pageQuery.getQueryBy();

         if(queryBy!=null&&!queryBy.isEmpty())
        setQueryBy(standardQueryWrapper, queryBy);

         Page page = new PageQuery<Standard>().setPage(pageQuery);

         page(page, standardQueryWrapper);
         List<Standard> records = page.getRecords();
         Map<String, StandardDto> standardDtos =
                 records.stream().collect(Collectors.toMap(Standard::getStandardId, standard -> {
             StandardDto standardDto = new StandardDto();


             standardDto.setStandard(standard);
;
             return standardDto;
         }));
         fillData(standardDtos,queryBy);




         return BaseResponse.ok(new PageDto(page,standardDtos));

     }

    private void fillData(Map<String, StandardDto> standardDtos,Map<String,String> queryBy) {

        QueryWrapper<HeavyMetal> heavyMetalQueryWrapper = new QueryWrapper<>();
        QueryWrapper<NonHeavyMetal> nonHeavyMetalQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Mineral> mineralQueryWrapper = new QueryWrapper<>();
        QueryWrapper<Radiation> radiationQueryWrapper = new QueryWrapper<>();

        if(queryBy!=null);
        {  Set<String> ids = standardDtos.keySet();
            setBelong(heavyMetalQueryWrapper, nonHeavyMetalQueryWrapper, mineralQueryWrapper, radiationQueryWrapper,ids);
        }
        List<Map<String, Object>> heavyMetals = iHeavyMetalService.listMaps(heavyMetalQueryWrapper);
        List<Map<String, Object>> minerals = iMineralService.listMaps(mineralQueryWrapper);
        List<Map<String, Object>> nonHeavys = iNonHeavyMetalService.listMaps(nonHeavyMetalQueryWrapper);
        List<Radiation> radiationList = iRadiationService.list(radiationQueryWrapper);
        fillDataForStandard(StandardDto::getHeavyMentals,StandardDto::setHeavyMentals,heavyMetals,standardDtos);
        fillDataForStandard(StandardDto::getMinerals,StandardDto::setMinerals,minerals,standardDtos);
        fillDataForStandard(StandardDto::getNonHeavyMentals,StandardDto::setNonHeavyMentals,nonHeavys,standardDtos);
       addRadtion(standardDtos,radiationList);

    }

    private void addRadtion(Map<String, StandardDto> standardDtos, List<Radiation> radiationList)
    {


        for (int i = 0; i <radiationList.size() ; i++)
        {
            Radiation radiation = radiationList.get(i);
            String radiationBelong = radiation.getRadiationBelong();
            StandardDto standardDto = standardDtos.get(radiationBelong);
            List<Radiation> radiations = standardDto.getRadiations();
            if(radiations==null)
            {
                List<Radiation> radiationList1 = new ArrayList<Radiation>();
                radiationList1.add(radiation);
                standardDto.setRadiations(radiationList1);
            }

            else {

                radiations.add(radiation);
            }
        }


    }

    private void setBelong(QueryWrapper<HeavyMetal> heavyMetalQueryWrapper, QueryWrapper<NonHeavyMetal> nonHeavyMetalQueryWrapper
            , QueryWrapper<Mineral> mineralQueryWrapper, QueryWrapper<Radiation> radiationQueryWrapper, Set<String> ids)
    {

         setQueryBy(heavyMetalQueryWrapper,ids,HEAVY_METAL_PREFIX);
         setQueryBy(nonHeavyMetalQueryWrapper,ids,NON_HEAVY_METAL_PREFIX);
         setQueryBy(mineralQueryWrapper,ids,MINERAL_PREFIX);
          setQueryBy(radiationQueryWrapper,ids,RADIATION_PREFIX);


    }

    private <T> void setQueryBy(QueryWrapper<T> standardQueryWrapper, Map<String, String> queryBy)
    {
        for (Map.Entry<String, String> entry : queryBy.entrySet()) {
         standardQueryWrapper.like(entry.getKey(),entry.getValue());

        }

    }
    private  <T>  void setQueryBy(QueryWrapper<T> standardQueryWrapper, Set<String> ids,String prefix) {
       prefix+="belong";
        standardQueryWrapper.in(prefix,ids);




    }

  public     void fillDataForStandard(Function<StandardDto,Map<String,Map<String,Object>>> functionGet
          , SetFunction<StandardDto, Map<String,Map<String,Object>>> functionSet,
                              List<Map<String,Object>> dataList, Map<String, StandardDto> stringStandardDtoHashMap)
 {


     for (int i = 0; i < dataList.size(); i++) {
         Map<String, Object> map = dataList.get(i);


         String o =(String)  map.get("belong");
         String name = (String)map.get("name");
         //遍历

         StandardDto standardDto = stringStandardDtoHashMap.get(o);
         Map<String,Map<String,Object>> data= functionGet.apply(standardDto);
         if (data==null)
         {
             HashMap<String, Map<String, Object>> stringMapHashMap = new HashMap<>();
             stringMapHashMap.put(name,null);
             data=stringMapHashMap;
              functionSet.setField(standardDto,data);
         }
         Map<String, Object> stringObjectMap = data.get(name);

         if(stringObjectMap==null) {
             HashMap<String, Object> realData = new HashMap<>();
             realData.put("max",map);

           data.put(name,realData);


         }
           else
           {
               HashMap<String,Object> maxNow = ((HashMap<String,Object>)stringObjectMap.get("max"));
               double dataValueOld = Double.parseDouble(((String)maxNow.get("data")));

               double dataValueNew=Double.parseDouble(((String)map.get("data")));
               if(dataValueNew<dataValueOld) {
                   stringObjectMap.put("min", map);
                   continue;
               }
                 stringObjectMap.put("min",maxNow);

                 stringObjectMap.put("max",map);


           }



     }




 }
}
